package practica2;

import java.util.Random;

import cap3.Pila;

/**
*Presenta cuatro métodos para trabajar con pilas de referencias a objetos genéricos de una 
*misma clase.
*/

public class OperarPila {
	
	/**
	 * Pre: P = [P 1, P 2, ..., P Cima]
	 * Post : P = [P 1, P 2, ..., P Cima] AND presenta por pantalla un listado de los datos apilados
	 * comenzando por la cima, P Cima, y acabando por el del fondo de la pila , P 1, a razón
	 * de un dato por línea :
	 * P Cima
	 * ...
	 * P 2
	 * P 1
	 * Para presentar por pantalla los datos de la pila se debe invocar el método toString () 
	 * definido en la clase D.
	 *	
	 */
	public static <D> void mostrar(Pila <D> P){
		D dato;
		if (!P.vacia()){
			dato=P.desapilar();						
			System.out.println(dato.toString());	//Ojo con el orden de mostrar, ya que si lo colocamos encima de system da el orden inverso
			mostrar(P);
			P.apilar(dato);
		}		
	}
	
	/**
	 * Pre: P = [P 1, P 2, ..., P K] AND K>=0
 	 * Post : P = [P 1, P 2, ..., P K] AND numDatos(P)=K
	 */
	public static <D> int numDatos(Pila <D> P){
		
		D dato;
		int n;
		if (!P.vacia()){
			dato=P.desapilar();			
			n=(1+numDatos(P));
			P.apilar(dato);
			return n;
			
		}
		else{ return 0;}		
	}
	
	/**
	 * Pre: P = [P 1, P 2, ..., P Cima] AND numDatos(P)>0
 	 * Post : P = [P 2, ..., P Cima]
	 */	
	public static <D> void eliminarFondo(Pila <D> P){
		
		D dato;
		int n=numDatos(P);
		if (n==1){P.desapilar();}
		else {
			dato=P.desapilar();
			n--;
			eliminarFondo(P);
			P.apilar(dato);
		}
		
		
		
	}
	/**
	 * Pre: P = [P 1, P 2, ..., P Cima] AND numDatos(P)>=0
	 * Post : P = [nuevo, P 1, P 2, ..., P Cima]

	 */
	
	public static <D> void insertarEnFondo(Pila <D> P,D nuevo){
		
		D dato;
		if(P.vacia()){P.apilar(nuevo);}
		else{
			dato=P.desapilar();
			insertarEnFondo(P,nuevo);
			P.apilar(dato);
		}
		
	}
	
	public static void main (String[] argumentos) {
	      Random generador = new Random();
	      /*
	       * Define una pila de enteros, apila en ella 10 enteros entre 1 y 1000 generados
	       * de forma pseudoaleatoria e informa por pantalla de los datos apilados
	       */
	      Pila <Integer> pila = new Pila <Integer>(100);
	      for (int i=1; i<=10; ++i) {
	         int n = new Integer(1+generador.nextInt(1000));
	         pila.apilar(n);
	         System.out.printf("Apilado: %d%n", n);
	      }
	      System.out.println();
	      
	      
	      insertarEnFondo(pila, 500);
	      mostrar(pila);
	      System.out.println();
	      System.out.println("Hay:");	      
	      System.out.println(numDatos(pila));
	      System.out.println();
	      eliminarFondo(pila);
	      mostrar(pila);
	      
	    
	   }
		

}
